﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System.Linq;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using FTI.Logging;

namespace FTI.Testing
{
    [TestClass]
    public class CompositionTest
    {
        public static string ExtensionFolder = "";

        [ImportMany(typeof(ISource))]
        IEnumerable<ISource> Sources { get; set; }

        [ImportMany(typeof(IDestination))]
        IEnumerable<IDestination> Destinations { get; set; }

        private static bool setup = false;

        [ClassInitialize]
        public static void ClassInitialize(TestContext oContext)
        {
            ExtensionFolder = String.Format("{0}\\Extensions", Environment.CurrentDirectory);

            if (!EventLogging.SourceExists)
            {
                Process
                    oSetupProcess = new Process();

                oSetupProcess.StartInfo = new ProcessStartInfo("fti.exe", "-setup")
                {
                    UseShellExecute = true,
                    Verb = "runas",
                    WorkingDirectory = Environment.CurrentDirectory,
                    CreateNoWindow = true
                };

                oSetupProcess.Start();
            }
        }

        [ClassCleanup]
        public static void ClassCleanup()
        {
            EventLog.DeleteEventSource(EventLogging.source);
        }

        [TestMethod()]
        public void InitializeCompositionContainer()
        {
            FTI.Composition oComposition = new Composition();

            Assert.IsNotNull(oComposition.Log);
        }

        [TestMethod]
        public void WriteEventToEventLog()
        {
            FTI.Composition oComposition = new Composition();

            Assert.IsTrue(oComposition.Log.Write("test message from unit testing", EventLogEntryType.Information, SystemCategory.Testing), "could not write to log for any reason.");
        }

        [TestMethod]
        public void LoadTheSourceAndDestinationExtensions()
        {
            FTI.Composition oComposition = new Composition();

            Assert.IsTrue(Sources == null || Sources.Count() == 0, "Sources enumerable list is not empty or null.");
            Assert.IsTrue(Destinations == null || Destinations.Count() == 0, "Destinations enumerable list is not empty or null.");

            oComposition.ComposeContainer(this);

            Assert.IsTrue(
                    Sources != null && 
                    Sources.Count() > 0 && 
                    Sources.Where(X => X.Name.Equals("Milliman Benefits")).Count() == 1, 
                "Sources enumerable list has not composed correctly.");

            Assert.IsTrue(
                    Destinations != null &&
                    Destinations.Count() > 0 &&
                    Destinations.Where(X => X.Name.Equals("MS Money")).Count() >= 1 &&
                    Destinations.Where(X => X.Name.Equals("Quicken")).Count() >= 1,
                "Destination enumerable list has not composed correctly.");

            Assert.IsTrue(
                Sources.Single(X =>
                    X.Name.Equals("Milliman Benefits")).Log != null, 
                "Failed to compose the Log Property on the Source Entity.");

            Assert.IsTrue(
                Destinations.Single(X =>
                    X.Name.Equals("MS Money")).Log != null &&
                Destinations.Single(X =>
                    X.Name.Equals("Quicken")).Log != null,
                "Failed to compose the Log Property on one or more Destination Entity.");
        }
    }
}
